<?php
function jsonForObject($class = "")
{
    $req = request();
    try {
        $contentType = $req->getHeader('content-type');
        if (!$contentType || false === stripos($contentType[0], \Swoft\Http\Message\ContentType::JSON)) {
            return false;
        }
        $raw = $req->getBody()->getContents();
        $map = json_decode($raw, true);// key=>value数组
        if ($class == "") return $map;
        $class_obj = new ReflectionClass($class);//反射对象
        $class_instance = $class_obj->newInstance();//根据反射对象创建实例
        $methods = $class_obj->getMethods(ReflectionMethod::IS_PUBLIC);
        foreach ($methods as $method) {

            if (preg_match("/^set(\w+)/", $method->getName(), $matches)) {
                //echo $matches[1].PHP_EOL; //这里得到了方法名，如方法名是setProdId，则得到ProdId
                invokeSetterMethod($matches[1], $class_obj, $map, $class_instance);
            }
        }
        return $class_instance;
    } catch (Exception $exception) {
        echo $exception->getMessage();
        return false;
    }
}

function mapToModelsArrary(array $maps, $class, $fill = [], $toarray = false)
{
    $ret = [];
    foreach ($maps as $map) {
        $getObject = mapToModel($map, $class);
        if ($getObject) {
            if ($fill && count($fill) > 0)
                $getObject->fill($fill);
            if ($toarray)
                $ret[] = $getObject->getModelAttributes();//数组
            else
                $ret[] = $getObject; //实体对象
        }
    }
    return $ret;
}

function mapToModel(array $map, $class)
{//把数组映射成实体 (一维数组)
    try {
        $class_obj = new ReflectionClass($class);
        $class_instance = $class_obj->newInstance();//根据反射对象创建实例
        $methods = $class_obj->getMethods(ReflectionMethod::IS_PUBLIC);
        foreach ($methods as $method) {
            if (preg_match("/^set(\w+)/", $method->getName(), $matches)) {
                invokeSetterMethod($matches[1], $class_obj, $map, $class_instance);
            }
        }
        return $class_instance;
    } catch (Exception $e) {
        return null;
    }
}

function invokeSetterMethod($name, ReflectionClass $class_obj, $jsonMap, &$class_instance)
{
    //好比 把ProdId 转化成Prod_Id
    $filter_name = strtolower(preg_replace("/(?<=[a-z])([A-Z])/", "_$1", $name));
    //把ProdId 转化成prodId
    $filter_name_ForSwoft = lcfirst($name);// ucfirst
    $props = $class_obj->getProperties(ReflectionProperty::IS_PRIVATE);

    foreach ($props as $prop) {
        if (strtolower($prop->getName()) == $filter_name || $prop->getName() == $filter_name_ForSwoft) { //存在对应的私有属性
            $method = $class_obj->getMethod("set" . $name);
            $args = $method->getParameters();//取出参数
            if (count($args) == 1 && isset($jsonMap[$filter_name])) {
                $method->invoke($class_instance, $jsonMap[$filter_name]);
            }

        }
    }
}
